<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>xeokit visual test</title>
    <link href="css/pageStyle.css" rel="stylesheet" />
  </head>

  <body>
    <canvas id="myCanvas"></canvas>
  </body>

  <script type="module">
    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import { Viewer, SceneModel, math } from "../../dist/xeokit-sdk.min.es.js";
    import { signalTestComplete } from "./lib/utils.js";

    let geometryNum = 0;

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer and arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
      canvasId: "myCanvas",
      transparent: true,
      dtxEnabled: true,
      logarithmicDepthBufferEnabled: true,
    });

    viewer.scene.camera.eye = [+1000000000, 0, 100];
    viewer.scene.camera.look = [+1000000000, 0, 0];
    viewer.scene.camera.up = [0, 1, 0];

    //------------------------------------------------------------------------------------------------------------------
    // Create a SceneModel representing a table with four legs, using geometry batching
    //------------------------------------------------------------------------------------------------------------------

    const sceneModel = new SceneModel(viewer.scene, {
      id: "tables",
      isModel: true,
      scale: [1, 1, 1],
      rotation: [0, 0, 0],
      edges: true,
    });

    //-----------------------------------------------------------
    // Create several origin points
    //-----------------------------------------------------------

    const OFFSET = 12.5;

    const origins = [
      [0, 0, 0],
      [OFFSET, 0, 0],
      [0, 0, OFFSET],
      [OFFSET, 0, OFFSET],
    ];

    //-----------------------------------------------------------
    // Within out SceneModel, create a simple table model
    // at each of our origins. This will result in several
    // tables, positioned very far apart from each other.
    //-----------------------------------------------------------

    for (let i = 0, len = origins.length; i < len; i++) {
      buildTable(sceneModel, origins[i]);
    }

    //------------------------------------------------------------
    // Finalize the SceneModel.
    //------------------------------------------------------------

    sceneModel.finalize();

    sceneModel.position = [1000000000, 0, 0];
    sceneModel.rotation = [30, 30, 0];

    viewer.cameraFlight.jumpTo(sceneModel);

    //------------------------------------------------------------------------------------------------------------------
    // Creates a simple table-shaped model with the given SceneModel,
    // without reusing geometry, and centered at the given origin
    //------------------------------------------------------------------------------------------------------------------

    function buildTable(sceneModel, origin) {
      const geometryId = "myBoxGeometry" + geometryNum++;

      sceneModel.createGeometry({
        id: geometryId,
        primitive: "triangles",
        positions: [
          1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1,
          1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1,
          -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
          -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
        ],
        indices: [
          0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14,
          12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23,
        ],
      });

      let meshId = math.createUUID();

      sceneModel.createMesh({
        id: meshId,
        origin: origin, // This mesh's positions and transforms are relative to the origin
        primitive: "triangles",
        geometryId,
        position: [-4, -6, -4],
        scale: [1, 3, 1],
        rotation: [0, 0, 0],
        color: [1, 0.3, 0.3],
      });

      sceneModel.createEntity({
        meshIds: [meshId],
        isObject: true,
      });

      meshId = math.createUUID();

      sceneModel.createMesh({
        id: meshId,
        origin: origin,
        primitive: "triangles",
        geometryId,
        position: [4, -6, -4],
        scale: [1, 3, 1],
        rotation: [0, 0, 0],
        color: [0.3, 1.0, 0.3],
      });

      sceneModel.createEntity({
        meshIds: [meshId],
        isObject: true,
      });

      meshId = math.createUUID();

      sceneModel.createMesh({
        id: meshId,
        origin: origin,
        geometryId,
        position: [4, -6, 4],
        scale: [1, 3, 1],
        rotation: [0, 0, 0],
        color: [0.3, 0.3, 1.0],
      });

      sceneModel.createEntity({
        meshIds: [meshId],
        isObject: true,
      });

      meshId = math.createUUID();

      sceneModel.createMesh({
        id: meshId,
        origin: origin,
        geometryId,
        position: [-4, -6, 4],
        scale: [1, 3, 1],
        rotation: [0, 0, 0],
        color: [1.0, 1.0, 0.0],
      });

      sceneModel.createEntity({
        meshIds: [meshId],
        isObject: true,
      });

      meshId = math.createUUID();

      sceneModel.createMesh({
        id: meshId,
        origin: origin,
        geometryId,
        position: [0, -3, 0],
        scale: [6, 0.5, 6],
        rotation: [0, 0, 0],
        color: [1.0, 0.3, 1.0],
      });

      sceneModel.createEntity({
        meshIds: [meshId],
        isObject: true,
      });
    }

    //------------------------------------------------------------------------------------------------------------------
    // Mouse hover to snap to vertices
    //------------------------------------------------------------------------------------------------------------------

    const markerDiv = document.createElement("div");
    const canvas = viewer.scene.canvas.canvas;
    canvas.parentNode.insertBefore(markerDiv, canvas);

    markerDiv.style.background = "black";
    markerDiv.style.border = "2px solid blue";
    markerDiv.style.borderRadius = "20px";
    markerDiv.style.width = "10px";
    markerDiv.style.height = "10px";
    markerDiv.style.margin = "-200px -200px";
    markerDiv.style.zIndex = "100";
    markerDiv.style.position = "absolute";
    markerDiv.style.pointerEvents = "none";

    viewer.scene.input.on("mousemove", function (canvasPos) {
      const snapPickResult = viewer.scene.pick({
        canvasPos: canvasPos,
        snapRadius: 30,
        snapToEdge: true, // Default is true
        snapToVertex: false, // Default is true
      });

      if (snapPickResult && snapPickResult.snappedCanvasPos) {
        markerDiv.style.marginLeft = `${
          snapPickResult.snappedCanvasPos[0] - 10
        }px`;
        markerDiv.style.marginTop = `${
          snapPickResult.snappedCanvasPos[1] - 10
        }px`;
        markerDiv.style.background = "greenyellow";
        markerDiv.style.border = "3px solid green";
      } else {
        markerDiv.style.marginLeft = `${canvasPos[0] - 10}px`;
        markerDiv.style.marginTop = `${canvasPos[1] - 10}px`;
        markerDiv.style.background = "white";
        markerDiv.style.border = "1px solid black";
      }
    });

    window.viewer = viewer;
    signalTestComplete(viewer);
  </script>
</html>
